#region File Description
//-----------------------------------------------------------------------------
// GameplayScreen.cs
//
// Microsoft XNA Community Game Platform
// Copyright (C) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
#endregion

#region Using Statements
using System;
using System.Threading;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using GGJ.Sprites;
using System.Collections.Generic;
using Microsoft.Xna.Framework.Media;
#endregion

namespace GGJ
{
    /// <summary>
    /// This screen implements the actual game logic. It is just a
    /// placeholder to get the idea across: you'll probably want to
    /// put some more interesting gameplay in here!
    /// </summary>
    class GameplayScreen : GameScreen
    {
        #region Fields

        public enum Level
        {
            Kitchen = 0,
            Backyard
        }

        Level type;

        ContentManager content;

        Texture2D flySprites, background1, background2, trapSprites, manaBar;

        Flies flies;

        Ennemies ennemies;

        WaitingFlies waitingFlies;

        KilledFlies killedFlies;

        Rectangle sourceBackground1, sourceBackground2;

        double manaPercent = 100;

        private bool isSlowMotion = false;

        float pauseAlpha;

        private Boolean paused = false;

        int iSlowMotion = 0;

        double elapsed = 0.0d;

        double elapsedSinceLevelUp = 0.0d;

        #endregion

        #region Initialization


        /// <summary>
        /// Constructor.
        /// </summary>
        public GameplayScreen(Level level)
        {
            TransitionOnTime = TimeSpan.FromSeconds(1.5);
            TransitionOffTime = TimeSpan.FromSeconds(0.5);

            sourceBackground1 = new Rectangle(0, 0, 800, 600);
            sourceBackground2 = new Rectangle(0, 0, 800, 600);

            this.type = level;

            InitAllSpeed();

            MediaPlayer.Pause();
            MediaPlayer.Play(Program.buzzWalkSound);
        }

        public void InitAllSpeed()
        {
            Program.speedEnnemys = 3;
            Program.speedFlies = 3;
            Program.speedParallax1 = 1;
            Program.speedParallax2 = 2;
        }

        /// <summary>
        /// Load graphics content for the game.
        /// </summary>
        public override void LoadContent()
        {
            if (content == null)
                content = new ContentManager(ScreenManager.Game.Services, "Content");


            switch (type)
            {
                case Level.Kitchen:
                    background1 = content.Load<Texture2D>("background");
                    background2 = content.Load<Texture2D>("ground");
                break;
                case Level.Backyard:
                    background1 = content.Load<Texture2D>("background2");
                    background2 = content.Load<Texture2D>("ground2");
                break;
            }
        
            flySprites = content.Load<Texture2D>("fly");
            trapSprites = content.Load<Texture2D>("trap");
            manaBar = content.Load<Texture2D>("HealthBar2");

            flies = new Flies(flySprites, 400, 300);

            ennemies = new Ennemies(trapSprites,type);

            waitingFlies = new WaitingFlies(flySprites);

            killedFlies = new KilledFlies(flySprites);

            // A real game would probably have more content than this sample, so
            // it would take longer to load. We simulate that by delaying for a
            // while, giving you a chance to admire the beautiful loading screen.
            Thread.Sleep(1000);

            // once the load has finished, we use ResetElapsedTime to tell the game's
            // timing mechanism that we have just finished a very long frame, and that
            // it should not try to catch up.
            ScreenManager.Game.ResetElapsedTime();
        }


        /// <summary>
        /// Unload graphics content used by the game.
        /// </summary>
        public override void UnloadContent()
        {
            content.Unload();
        }


        #endregion

        #region Update and Draw


        /// <summary>
        /// Updates the state of the game. This method checks the GameScreen.IsActive
        /// property, so the game will stop updating when the pause menu is active,
        /// or if you tab away to a different application.
        /// </summary>
        public override void Update(GameTime gameTime, bool otherScreenHasFocus,
                                                       bool coveredByOtherScreen)
        {
            base.Update(gameTime, otherScreenHasFocus, false);

            // Gradually fade in or out depending on whether we are covered by the pause screen.
            if (coveredByOtherScreen)
                pauseAlpha = Math.Min(pauseAlpha + 1f / 32, 1);
            else
                pauseAlpha = Math.Max(pauseAlpha - 1f / 32, 0);


            if (!paused)
            {
                elapsed += gameTime.ElapsedGameTime.TotalSeconds;

                elapsedSinceLevelUp += gameTime.ElapsedGameTime.TotalSeconds;

                if (elapsedSinceLevelUp > 10.0d)
                {
                    Program.speedFlies++;
                    Program.speedEnnemys++;
                    Program.speedParallax1++;
                    Program.speedParallax2++;
                    elapsedSinceLevelUp = 0.0d;
                }
            }
               

            if (IsActive)
            {
                if (isSlowMotion)
                {
                    if (manaPercent > 0)
                        manaPercent -= 0.2;
                    else
                        isSlowMotion = false;
                }

                if (isSlowMotion)
                {
                    iSlowMotion = (iSlowMotion + 1) % 2;
                    sourceBackground1.X = (sourceBackground1.X + iSlowMotion) % sourceBackground1.Width;
                    sourceBackground2.X = (sourceBackground2.X + 1) % sourceBackground2.Width;
                }
                else
                {
                    if (manaPercent < 100)
                        manaPercent += 0.1;

                    sourceBackground1.X = (sourceBackground1.X + Program.speedParallax1) % sourceBackground1.Width;
                    sourceBackground2.X = (sourceBackground2.X + Program.speedParallax2) % sourceBackground2.Width;
                }

                

                flies.Update(gameTime, isSlowMotion);
                ennemies.Update(gameTime, flies,killedFlies,isSlowMotion);
                waitingFlies.Update(gameTime, flies,ennemies,isSlowMotion);
                killedFlies.Update(gameTime, flies, isSlowMotion);

               

                if (flies.IsForcedToGoDown())
                    GamePad.SetVibration(PlayerIndex.One, 1.0f, 1.0f);
                else
                    GamePad.SetVibration(PlayerIndex.One, 0.0f, 0.0f);

                if (flies.getRealCount() == 0)
                {
                    StopChrono();
                    TimeSpan timeSpan = TimeSpan.FromSeconds(elapsed);
                    ScreenManager.AddScreen(new EndGameMenuScreen(type,timeSpan,killedFlies.getLost()), ControllingPlayer);
                }
            }
           
        }

        public void StopChrono()
        {
            paused = true;
           
        }

        public void StartChrono()
        {
            paused = false;
        }

        /// <summary>
        /// Lets the game respond to player input. Unlike the Update method,
        /// this will only be called when the gameplay screen is active.
        /// </summary>
        public override void HandleInput(InputState input)
        {
            if (input == null)
                throw new ArgumentNullException("input");

            // Look up inputs for the active player profile.
            int playerIndex = (int)ControllingPlayer.Value;

            KeyboardState keyboardState = input.CurrentKeyboardStates[playerIndex];
            GamePadState gamePadState = input.CurrentGamePadStates[playerIndex];

            // The game pauses either if the user presses the pause button, or if
            // they unplug the active gamepad. This requires us to keep track of
            // whether a gamepad was ever plugged in, because we don't want to pause
            // on PC if they are playing with a keyboard and have no gamepad at all!
            bool gamePadDisconnected = !gamePadState.IsConnected &&
                                       input.GamePadWasConnected[playerIndex];

            if (input.IsPauseGame(ControllingPlayer) || gamePadDisconnected)
            {
                StopChrono();
                ScreenManager.AddScreen(new PauseMenuScreen(this), ControllingPlayer);
            }
            else
            {
                // flies
                if (Keyboard.GetState().IsKeyDown(Keys.Up) || (gamePadState.ThumbSticks.Left.Y > 0))
                    flies.SetMovement(FliesMovement.Up);
                else if (Keyboard.GetState().IsKeyDown(Keys.Down) || (gamePadState.ThumbSticks.Left.Y < 0))
                    flies.SetMovement(FliesMovement.Down);
                else
                    flies.SetMovement(FliesMovement.None);

                // slow motion
                if (Keyboard.GetState().IsKeyDown(Keys.Enter) || gamePadState.IsButtonDown(Buttons.A))
                {
                    if (isSlowMotion)
                    {
                        isSlowMotion = false;
                    }
                    else
                    {
                        if (manaPercent  > 0)
                        {
                            isSlowMotion = true;
                        }
                    }
                }
            }
        }


        /// <summary>
        /// Draws the gameplay screen.
        /// </summary>
        public override void Draw(GameTime gameTime)
        {
            // This game has a blue background. Why? Because!
            ScreenManager.GraphicsDevice.Clear(ClearOptions.Target,
                                               Color.CornflowerBlue, 0, 0);

            // Our player and enemy are both actually just text strings.
            SpriteBatch spriteBatch = ScreenManager.SpriteBatch;

            spriteBatch.Begin(SpriteSortMode.Deferred, null, SamplerState.LinearWrap, null, null);

            Rectangle destination = new Rectangle(0, 0, 800, 600);

            spriteBatch.Draw(background1, destination, sourceBackground1, Color.White);
            spriteBatch.Draw(background2, destination, sourceBackground2, Color.White);

            flies.Draw(spriteBatch);

            ennemies.Draw(spriteBatch);

            waitingFlies.Draw(spriteBatch);

            killedFlies.Draw(spriteBatch);

            //Draw the health for the health bar
            spriteBatch.Draw(manaBar, new Rectangle(800 / 2 - manaBar.Width / 2,

                  20, (int) (manaBar.Width * manaPercent / 100), 44),

                  new Rectangle(0, 45, (int) (manaBar.Width * manaPercent / 100), 44), Color.Green);


            //Draw the box around the health bar
            spriteBatch.Draw(manaBar, new Rectangle(800 / 2 - manaBar.Width / 2,
                  20, manaBar.Width, 44), new Rectangle(0, 0, manaBar.Width, 44), Color.White);


            String scoreString = (int)elapsed+" s";
            String teamString = "Army: " + flies.getRealCount();

            Color titleColor = new Color(0, 10, 192) * TransitionAlpha;
            float transitionOffset = (float)Math.Pow(TransitionPosition, 2);
            SpriteFont font = ScreenManager.Font;
            Vector2 origin = font.MeasureString(scoreString) / 2;
            Vector2 origin2 = font.MeasureString(teamString) / 2;
            Vector2 position = new Vector2(800 - (origin.X+5), origin.Y+20);
            Vector2 position2 = new Vector2(origin2.X , origin2.Y + 20);
            float titleScale = 1.0f;

      
            spriteBatch.DrawString(font, scoreString, position, titleColor, 0,
                                origin, titleScale, SpriteEffects.None, 0);
            spriteBatch.DrawString(font, teamString, position2, titleColor, 0,
                          origin2, titleScale, SpriteEffects.None, 0);

            spriteBatch.End();

            // If the game is transitioning on or off, fade it out to black.
            if (TransitionPosition > 0 || pauseAlpha > 0)
            {
                float alpha = MathHelper.Lerp(1f - TransitionAlpha, 1f, pauseAlpha / 2);

                ScreenManager.FadeBackBufferToBlack(alpha);
            }
        }


        #endregion
    }
}
